package server.datamodel;

import java.util.ArrayList;
import java.util.HashMap;

import server.ConnectionHandler;

public class CreepSmashGame {

		private Guide guide;
		private String name;
		private String ID;
		private int numPlayers;
		private boolean running;
		private boolean testGame;
		private User winner;
		private long nextIncome;
		private double speed;
		private HashMap<String, Tile> tiles= new HashMap<String, Tile>();
		private HashMap<String, UserAssets> users = new HashMap<String, UserAssets>();
		
		private ArrayList<ConnectionHandler> usersInThisGame = new ArrayList<ConnectionHandler>();
		
		public CreepSmashGame() {
			this.ID = Datamodel.generateID(this);
		}
		
		@Override
		public String toString() {
			return ID;
		}
		
		public void addTile(Tile tile) {
			if(!tiles.containsKey(tile.getID())) {
				tiles.put(tile.getID(), tile);
				tile.setGame(this);
			}
		}
		
		public void removeTile(Tile tile) {
			if(tiles.remove(tile.getID()) != null) {
				tile.setGame(null);
			}
		}
		
		public void addUserAssets(UserAssets user) {
			if(!users.containsKey(user.getID())) {
				users.put(user.getID(), user);
				user.setGame(this);
			}
			
			broadcast(this, "users", null, user);
		}
		
		public void removeUserAssets(UserAssets user) {
			if(users.remove(user.getID()) != null) {
				user.setGame(null);
			}
			
			broadcast(this, "users", user, null);
		}

		public Guide getGuide() {
			return guide;
		}

		public void setGuide(Guide guide) {
			if(this.guide != guide) {
				if(getGuide() != null) {
					Guide oldGuide = getGuide();
					this.guide = null;
					oldGuide.setGame(null);
				}
				this.guide = guide;
				if(getGuide() != null) {
					getGuide().setGame(this);
				}
			}
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getID() {
			return ID;
		}

		public void setID(String iD) {
			ID = iD;
		}

		public int getNumPlayers() {
			return numPlayers;
		}

		public void setNumPlayers(int numPlayers) {
			this.numPlayers = numPlayers;
		}

		public boolean isRunning() {
			return running;
		}

		public void setRunning(boolean running) {
			this.running = running;
		}

		public boolean isTestGame() {
			return testGame;
		}

		public void setTestGame(boolean testGame) {
			this.testGame = testGame;
		}

		public User getWinner() {
			return winner;
		}

		public void setWinner(User winner) {
			this.winner = winner;
		}

		public long getNextIncome() {
			return nextIncome;
		}

		public void setNextIncome(long nextIncome) {
			this.nextIncome = nextIncome;
		}

		public double getSpeed() {
			return speed;
		}

		public void setSpeed(double speed) {
			this.speed = speed;
		}
		
		public HashMap<String, Tile> getTiles() {
			return tiles;
		}
		
		public Tile getTile(String ID) {
			return tiles.get(ID);
		}
		
		public UserAssets getUserAssets(String ID) {
			return users.get(ID);
		}
		
		public void addUserInThisGame(ConnectionHandler connectionHandler) {
			usersInThisGame.add(connectionHandler);
		}
		
		public void removeUsersInThisGame(ConnectionHandler connectionHandler) {
			usersInThisGame.remove(connectionHandler);
		}
		
		public void broadcast(String message) {
			for(ConnectionHandler c: usersInThisGame) {
				c.sendMessage(message);
			}
		}
		
		public void broadcast(Object src, String property, Object oldValue, Object newValue) {
			if(oldValue == null && newValue == null) {
				return;
			}
			
			StringBuffer buffer = new StringBuffer();
			buffer.append("{\"@ts\":\"" + System.currentTimeMillis() + "\"");
			buffer.append(",\"@src\":\"" + src.toString() + "\"");
			buffer.append(",\"@prop\":\"" + property + "\"");
			
			if(oldValue != null) {
				buffer.append(",\"@ov\":\"" + oldValue.toString() + "\"");
			}
			
			if(newValue != null) {
				buffer.append(",\"@nv\":\"" + newValue.toString() + "\"");
			}
			
			buffer.append("}");
			
			broadcast(buffer.toString());
		}
		
		public void broadcast(Object src, String property, String oldValue, String newValue) {
			if(oldValue == null && newValue == null) {
				return;
			}
			
			StringBuffer buffer = new StringBuffer();
			buffer.append("{\"@ts\":\"" + System.currentTimeMillis() + "\"");
			buffer.append(",\"@src\":\"" + src.toString() + "\"");
			buffer.append(",\"@prop\":\"" + property + "\"");
			
			if(oldValue != null) {
				buffer.append(",\"@ov\":\"" + oldValue + "\"");
			}
			
			if(newValue != null) {
				buffer.append(",\"@nv\":\"" + newValue + "\"");
			}
			
			buffer.append("}");
			
			broadcast(buffer.toString());
		}
		
		public HashMap<String, UserAssets> getUsers() {
			return users;
		}
}
